<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="author" content="Taffy">
    
    <meta name="description" content="纸上得来终觉浅，绝知此事要躬行！">
    
    
    
    
    
    
    <title>C#多线程 | 标签 | 阿飞</title>
    <link href=”https://taffyblog.github.io“ rel=”prefetch” />

    <link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/aos.css">
<link rel="stylesheet" href="/css/style.css">
    <script src="/js/jquery.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
    <script src="/js/aos.js"></script>
    <script src="/js/highslide/highslide-full.min.js"></script>
    <link rel="stylesheet" href="/js/highslide/highslide.css">
    <style type="text/css">
        @media (max-width: 768px) {
            body {
                background-color: #f0f0f0;
                background: url('/imgs/xsbg.gif');
                background-attachment: fixed;
            }
        }
    </style>
    
    <!--<script type="text/javascript">
      if (document.images) {
        var avatar = new Image();
        avatar.src = '/imgs/avatar.jpg'
        var previews = 'preview1.jpg,preview2.jpg,preview3.jpg,preview4.jpg'.split(',')
        var previewsPreLoad = []
        for(var i = 0; i < length; i++) {
          previewsPreLoad.push(new Image())
          previewsPreLoad[previewsPreLoad.length - 1].src = '/imgs/preview' + previews[i]
        }
      }
    </script>-->
<link rel="stylesheet" href="/css/prism-vs.css" type="text/css">
<link rel="stylesheet" href="/css/prism-line-numbers.css" type="text/css"></head>
<body>
    <!-- 背景轮播图功能 -->
    <section class="hidden-xs">
    <ul class="cb-slideshow">
        <li><span>天若</span></li>
        <li><span>有情</span></li>
        <li><span>天亦老</span></li>
        <li><span>我为</span></li>
        <li><span>长者</span></li>
        <li><span>续一秒</span></li>
    </ul>
</section>
    <!-- 欧尼酱功能, 谁用谁知道 -->
    
    <div class="gal-menu gal-dropdown">
    <div class="circle" id="gal">
        <div class="ring">
            <a href="https://taffyblog.github.io" class="menuItem" style="left: 50%; top: 15%;">首页</a>
            
            <a class="menuItem" style="left: 80.3109%; top: 32.5%;">下一页</a>
            
            <a href="/archives" class="menuItem" style="left: 80.3109%; top: 67.5%;">归档</a>
            <a href="/about" class="menuItem" style="left: 50%; top: 85%;">关于</a>
            <a href="/message" class="menuItem" style="left: 19.6891%; top: 67.5%;">留言板</a>
            
            <a class="menuItem" style="left: 19.6891%; top: 32.5%;">上一页</a>
            
        </div>
        <audio id="audio" src="/imgs/oni.mp3"></audio>
    </div>
</div>
    
    <header class="navbar navbar-inverse" id="gal-header">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed"
                    data-toggle="collapse" data-target=".bs-navbar-collapse"
                    aria-expanded="false">
                <span class="fa fa-lg fa-reorder"></span>
            </button>
            <a href="https://taffyblog.github.io">
                
                <style>
                    #gal-header .navbar-brand {
                        height: 54px;
                        line-height: 24px;
                        font-size: 28px;
                        opacity: 1;
                        background-color: rgba(0,0,0,0);
                        text-shadow: 0 0 5px #fff,0 0 10px #fff,0 0 15px #fff,0 0 20px #228DFF,0 0 35px #228DFF,0 0 40px #228DFF,0 0 50px #228DFF,0 0 75px #228DFF;
                    }
                </style>
                <!-- 这里使用文字(navbar_text or config.title) -->
                <div class="navbar-brand">小飞</div>
                
            </a>
        </div>
        <div class="collapse navbar-collapse bs-navbar-collapse">
            <ul class="nav navbar-nav" id="menu-gal">
                
                
                <li class="">
                    <a href="/">
                        <i class="fa fa-home"></i>首页
                    </a>
                </li>
                
                
                
                <li class="">
                    <a href="/archives">
                        <i class="fa fa-archive"></i>归档
                    </a>
                </li>
                
                
                
                
                <li class="dropdown">
                    <!-- TODO 添加hover dropdown效果 -->
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"
                       aria-haspopup="true" aria-expanded="false" data-hover="dropdown">
                        <i class="fa fa-list"></i>分类
                    </a>
                    <ul class="dropdown-menu">
                        
                        
                        <li>
                            <a href="/categories/设计模式/">设计模式</a>
                        </li>
                        
                        <li>
                            <a href="/categories/前端/">前端</a>
                        </li>
                        
                        <li>
                            <a href="/categories/ORM/">ORM</a>
                        </li>
                        
                        
                        <li>
                            <a href="/categories">...</a>
                        </li>
                        
                        
                    </ul>
                </li>
                
                
                
                
                
                <li class="dropdown">
                    <!-- TODO 添加hover dropdown效果 -->
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"
                       aria-haspopup="true" aria-expanded="false" data-hover="dropdown">
                        <i class="fa fa-tags"></i>标签
                    </a>
                    <ul class="dropdown-menu">
                        
                        
                        <li>
                            <a href="/tags/结构型设计模式/">结构型设计模式</a>
                        </li>
                        
                        <li>
                            <a href="/tags/Javascript/">Javascript</a>
                        </li>
                        
                        <li>
                            <a href="/tags/EF6/">EF6</a>
                        </li>
                        
                        
                        <li>
                            <a href="/tags">...</a>
                        </li>
                        
                        
                    </ul>
                </li>
                
                
                
                
                <li class="">
                    <a href="/links">
                        <i class="fa fa-meanpath"></i>外链
                    </a>
                </li>
                
                
                
                <li class="">
                    <a href="/about">
                        <i class="fa fa-user"></i>关于我
                    </a>
                </li>
                
                
            </ul>
        </div>
    </div>
</header>
    <div id="gal-body">
        <div class="container">
            <div class="row">
                 <!-- link页面不显示侧边栏 -->
                
                    <div class="col-md-8 gal-right" id="mainstay">
                         
<article class="article well article-body" id="article">
    <div class="breadcrumb">
        <i class="fa fa-home"></i>
        <a href="https://taffyblog.github.io">阿飞</a>
        >
        <span>C#多线程</span>
    </div>
    
    <!-- 大型设备详细文章 -->
    <div class="hidden-xs">
        <div class="title-article">
            <h1>
                <a href="/2017/05/15/task_async/">C#多线程</a>
            </h1>
        </div>
        <div class="tag-article">
            
            <span class="label label-gal">
                <i class="fa fa-calendar"></i> 2017-05-15
            </span>
            
        </div>
    </div>
    <!-- 小型设备详细文章 -->
    <div class="visible-xs">
        <center>
            <div class="title-article">
                <h4>
                    <a href="/2017/05/15/task_async/">C#多线程</a>
                </h4>
            </div>
            <p>
                <i class="fa fa-calendar"></i> 2017-05-15
            </p>
            <p>
                
                
            </p>
        </center>
    </div>
     <!-- 文章 目录 -->
    <ol class="post-toc"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#多线程基础"><span class="post-toc-number">1.</span> <span class="post-toc-text">多线程基础</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#进程的概念"><span class="post-toc-number">1.1.</span> <span class="post-toc-text">进程的概念</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#线程的概念"><span class="post-toc-number">1.2.</span> <span class="post-toc-text">线程的概念</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#多线程的概念"><span class="post-toc-number">1.3.</span> <span class="post-toc-text">多线程的概念</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#多线程的好处"><span class="post-toc-number">1.4.</span> <span class="post-toc-text">多线程的好处</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#多线程的不利方面"><span class="post-toc-number">1.5.</span> <span class="post-toc-text">多线程的不利方面</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#何时使用多线程"><span class="post-toc-number">1.6.</span> <span class="post-toc-text">何时使用多线程</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#何时避免使用多线程"><span class="post-toc-number">1.7.</span> <span class="post-toc-text">何时避免使用多线程</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#使用Parallel类"><span class="post-toc-number">2.</span> <span class="post-toc-text">使用Parallel类</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#Parallel-For-循环"><span class="post-toc-number">2.1.</span> <span class="post-toc-text">Parallel.For() 循环</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#使用Parallel-Invoke-并行调用多个方法"><span class="post-toc-number">2.2.</span> <span class="post-toc-text">使用Parallel.Invoke()并行调用多个方法</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#使用Thread类"><span class="post-toc-number">3.</span> <span class="post-toc-text">使用Thread类</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#创建不带参数线程"><span class="post-toc-number">3.1.</span> <span class="post-toc-text">创建不带参数线程</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#创建带参数的线程"><span class="post-toc-number">3.2.</span> <span class="post-toc-text">创建带参数的线程</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#关于后台线程"><span class="post-toc-number">3.3.</span> <span class="post-toc-text">关于后台线程</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#控制线程"><span class="post-toc-number">3.4.</span> <span class="post-toc-text">控制线程</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#使用线程池"><span class="post-toc-number">4.</span> <span class="post-toc-text">使用线程池</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#创建线程"><span class="post-toc-number">4.1.</span> <span class="post-toc-text">创建线程</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#异步编程模型（APM）"><span class="post-toc-number">5.</span> <span class="post-toc-text">异步编程模型（APM）</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#使用BeginInvoke异步执行无返回值委托"><span class="post-toc-number">5.1.</span> <span class="post-toc-text">使用BeginInvoke异步执行无返回值委托</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#使用EndInvoke获取异步执行的返回结果"><span class="post-toc-number">5.2.</span> <span class="post-toc-text">使用EndInvoke获取异步执行的返回结果</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#基于任务的异步模式（TAP）"><span class="post-toc-number">6.</span> <span class="post-toc-text">基于任务的异步模式（TAP）</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#任务的创建"><span class="post-toc-number">6.1.</span> <span class="post-toc-text">任务的创建</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#任务等待和回调的异步任务"><span class="post-toc-number">6.2.</span> <span class="post-toc-text">任务等待和回调的异步任务</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#同步任务"><span class="post-toc-number">6.3.</span> <span class="post-toc-text">同步任务</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#对长时间运行的任务使用单独线程"><span class="post-toc-number">6.4.</span> <span class="post-toc-text">对长时间运行的任务使用单独线程</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#创建具有返回值的异步任务"><span class="post-toc-number">6.5.</span> <span class="post-toc-text">创建具有返回值的异步任务</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#延续的任务"><span class="post-toc-number">6.6.</span> <span class="post-toc-text">延续的任务</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#任务的层次结构（父-子任务）"><span class="post-toc-number">6.7.</span> <span class="post-toc-text">任务的层次结构（父/子任务）</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#线程等待、取消和异常处理"><span class="post-toc-number">7.</span> <span class="post-toc-text">线程等待、取消和异常处理</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#线程取消和异常处理"><span class="post-toc-number">7.1.</span> <span class="post-toc-text">线程取消和异常处理</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#线程等待：给Thread、ThreadPool封装异步回调方法"><span class="post-toc-number">7.2.</span> <span class="post-toc-text">线程等待：给Thread、ThreadPool封装异步回调方法</span></a></li></ol></li></ol>
    <div class="content-article">
        <h3 id="多线程基础"><a href="#多线程基础" class="headerlink" title="多线程基础"></a>多线程基础</h3><h4 id="进程的概念"><a href="#进程的概念" class="headerlink" title="进程的概念"></a>进程的概念</h4><p>当一个程序开始运行时，它就是一个进程，进程包括运行中的程序和程序所使用到的内存和系统资源。<br>而一个进程又是由多个线程所组成的。</p>
<h4 id="线程的概念"><a href="#线程的概念" class="headerlink" title="线程的概念"></a>线程的概念</h4><p>线程是程序中的一个执行流，每个线程都有自己的专有寄存器(栈指针、程序计数器等)，但代码区是共享的，即不同的线程可以执行同样的函数。</p>
<h4 id="多线程的概念"><a href="#多线程的概念" class="headerlink" title="多线程的概念"></a>多线程的概念</h4><p>多线程是指程序中包含多个执行流，即在一个程序中可以同时运行多个不同的线程来执行不同的任务，也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。</p>
<h4 id="多线程的好处"><a href="#多线程的好处" class="headerlink" title="多线程的好处"></a>多线程的好处</h4><p>可以提高CPU的利用率。在多线程程序中，一个线程必须等待的时候，CPU可以运行其它的线程而不是等待，这样就大大提高了程序的效率。</p>
<h4 id="多线程的不利方面"><a href="#多线程的不利方面" class="headerlink" title="多线程的不利方面"></a>多线程的不利方面</h4><ul>
<li>线程也是程序，所以线程需要占用内存，线程越多占用内存也越多； </li>
<li>多线程需要协调和管理，所以需要CPU时间跟踪线程； </li>
<li>线程之间对共享资源的访问会相互影响，必须解决竞用共享资源的问题；</li>
<li>线程太多会导致控制太复杂，最终可能造成很多Bug；</li>
</ul>
<h4 id="何时使用多线程"><a href="#何时使用多线程" class="headerlink" title="何时使用多线程"></a>何时使用多线程</h4><p>多线程程序一般被用来在后台执行耗时的任务。主线程保持运行，并且工作线程做它的后台工作。对于Windows Forms程序来说，如果主线程试图执行冗长的操作，键盘和鼠标的操作会变的迟钝，程序也会失去响应。由于这个原因，应该在工作线程中运行一个耗时任务时添加一个工作线程，即使在主线程上有一个有好的提示“处理中…”，以防止工作无法继续。这就避免了程序出现由操作系统提示的“没有相应”，来诱使用户强制结束程序的进程而导致错误。模式对话框还允许实现“取消”功能，允许继续接收事件，而实际的任务已被工作线程完成。BackgroundWorker恰好可以辅助完成这一功能。</p>
<p>在没有用户界面的程序里，比如说Windows Service， 多线程在当一个任务有潜在的耗时，因为它在等待另台电脑的响应（比如一个应用服务器，数据库服务器，或者一个客户端）的实现特别有意义。用工作线程完成任务意味着主线程可以立即做其它的事情。</p>
<p>另一个多线程的用途是在方法中完成一个复杂的计算工作。这个方法会在多核的电脑上运行的更快，如果工作量被多个线程分开的话（使用Environment.ProcessorCount属性来侦测处理芯片的数量）。</p>
<p>一个C#程序称为多线程的可以通过2种方式：明确地创建和运行多线程，或者使用.NET framework的暗中使用了多线程的特性——比如BackgroundWorker类, 线程池，threading timer，远程服务器，或Web Services或ASP.NET程序。在后面的情况，人们别无选择，必须使用多线程；一个单线程的ASP.NET web server不是太酷，即使有这样的事情；幸运的是，应用服务器中多线程是相当普遍的；唯一值得关心的是提供适当锁机制的静态变量问题。</p>
<h4 id="何时避免使用多线程"><a href="#何时避免使用多线程" class="headerlink" title="何时避免使用多线程"></a>何时避免使用多线程</h4><p>多线程也同样会带来缺点，最大的问题是它使程序变的过于复杂，拥有多线程本身并不复杂，复杂是的线程的交互作用，这带来了无论是否交互是否是有意的，都会带来较长的开发周期，以及带来间歇性和非重复性的bug。因此，要么多线程的交互设计简单一些，要么就根本不使用多线程。除非你有强烈的重写和调试欲望。</p>
<p>当用户频繁地分配和切换线程时，多线程会带来增加资源和CPU的开销。在某些情况下，太多的I/O操作是非常棘手的，当只有一个或两个工作线程要比有众多的线程在相同时间执行任务快的多。</p>
<h3 id="使用Parallel类"><a href="#使用Parallel类" class="headerlink" title="使用Parallel类"></a>使用Parallel类</h3><p>Parallel类是对线程的一个很好的抽象，位于System.Threading.Tasks名称空间中，提供了数据和任务的并行性。</p>
<p>Parallel类定义了并行的for和foreach的静态方法。对于C#的for和foreach语句而言，循环从一个线程中运行。Parallel使用多个任务，因此使用多个线程来完成这个作业。</p>
<h4 id="Parallel-For-循环"><a href="#Parallel-For-循环" class="headerlink" title="Parallel.For() 循环"></a>Parallel.For() 循环</h4><pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Stopwatch watch <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Stopwatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    watch<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment" spellcheck="true">//并行循环代码</span>
    ParallelLoopResult result <span class="token operator">=</span> Parallel<span class="token punctuation">.</span><span class="token function">For</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span>i<span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span>
        Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    watch<span class="token punctuation">.</span><span class="token function">Stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token punctuation">.</span>IsCompleted<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Parallel.For已完成,耗时:"</span> <span class="token operator">+</span> watch<span class="token punctuation">.</span>ElapsedMilliseconds<span class="token operator">+</span><span class="token string">"毫秒"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    watch<span class="token punctuation">.</span><span class="token function">Restart</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment" spellcheck="true">/********************************************************/</span>
    <span class="token comment" spellcheck="true">//普通循环代码</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    watch<span class="token punctuation">.</span><span class="token function">Stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"for已完成,耗时:"</span> <span class="token operator">+</span> watch<span class="token punctuation">.</span>ElapsedMilliseconds <span class="token operator">+</span> <span class="token string">"毫秒"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">ReadKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果如下:</p>
<pre class="line-numbers language-bash"><code class="language-bash">8
6
2
4
0
7
1
3
5
9
Parallel.For已完成,耗时:45毫秒
0
1
2
3
4
5
6
7
8
9
for已完成,耗时:132毫秒
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>由于Parallel.For是并行循环，所以输出结果是无序的。当Thread.Sleep中的值越大时，并行循环与for的耗时差距越大,在不加Thread.Sleep时,for循环比并行循环耗时更少。</p>
</blockquote>
<h4 id="使用Parallel-Invoke-并行调用多个方法"><a href="#使用Parallel-Invoke-并行调用多个方法" class="headerlink" title="使用Parallel.Invoke()并行调用多个方法"></a>使用Parallel.Invoke()并行调用多个方法</h4><pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 摘要:</span>
    <span class="token comment" spellcheck="true">//     尽可能并行执行提供的每个操作。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 参数:</span>
    <span class="token comment" spellcheck="true">//   actions:</span>
    <span class="token comment" spellcheck="true">//     要执行的 System.Action 数组。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 异常:</span>
    <span class="token comment" spellcheck="true">//   T:System.ArgumentNullException:</span>
    <span class="token comment" spellcheck="true">//     actions 参数为 null。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">//   T:System.AggregateException:</span>
    <span class="token comment" spellcheck="true">//     当 actions 数组中的任何操作引发异常时引发的异常。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">//   T:System.ArgumentException:</span>
    <span class="token comment" spellcheck="true">//     actions数组包含 null 个元素。</span>
    <span class="token comment" spellcheck="true">//public static void Invoke(params Action[] actions);</span>
    Parallel<span class="token punctuation">.</span><span class="token function">Invoke</span><span class="token punctuation">(</span>Fone<span class="token punctuation">,</span> Ftwo<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Fone</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Ftwo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果如下：</p>
<pre class="line-numbers language-bash"><code class="language-bash">0
4
5
6
7
8
9
1
2
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="使用Thread类"><a href="#使用Thread类" class="headerlink" title="使用Thread类"></a>使用Thread类</h3><h4 id="创建不带参数线程"><a href="#创建不带参数线程" class="headerlink" title="创建不带参数线程"></a>创建不带参数线程</h4><p>Thread类可以创建和控制线程，Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。下面我们用一个例子来解释怎样用Thread类来创建一个简单的线程:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    #region Thread无参数举例
    Thread th <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>ThreadChild<span class="token punctuation">)</span><span class="token punctuation">;</span>
    th<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Main Thread Start!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    #endregion
<span class="token punctuation">}</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">ThreadChild</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Child Thread Start!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果如下</p>
<pre class="line-numbers language-bash"><code class="language-bash">Main Thread Start<span class="token operator">!</span>
Child Thread Start<span class="token operator">!</span> 
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<blockquote>
<p>程序运行的结果不能保证哪个先输出，因为线程是由操作系统调度，每次哪个线程在前面可以不同</p>
</blockquote>
<h4 id="创建带参数的线程"><a href="#创建带参数的线程" class="headerlink" title="创建带参数的线程"></a>创建带参数的线程</h4><p>上面的例子演示了怎样用<code>Thread</code>类来创建一个不带传参的线程，下面我门来创建一个带传入参数的线程。给线程传递参数，有两种方式:</p>
<ul>
<li>一种是使用带<code>ParameterizedThreadStart</code>委托参数的Thread的构造函数 。</li>
<li>一种是定义一个自定义类。首先我们使用<code>ParameterizedThreadStart</code>委托来创建有传入参数的类。</li>
</ul>
<p>使用<code>ParameterizedThreadStart</code>，线程的入口（线程调用的方法）必须有一个<code>Object</code>类型的参数，使用Object我们首先想到的就是类型不安全。而且在执行线程的时候多半有装箱拆箱操作。我们先用这种方式来创建一个带传入参数的线程：</p>
<pre class="line-numbers language-java"><code class="language-java"> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>     
    #region 使用parameterizedThreadStart委托执行带参数的委托
    Thread th2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>Thread_param<span class="token punctuation">)</span><span class="token punctuation">;</span>
    th2<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    #endregion         
<span class="token punctuation">}</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Thread_param</span><span class="token punctuation">(</span>object msg<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> message <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>msg<span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Result:{0}"</span><span class="token punctuation">,</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果：</p>
<pre class="line-numbers language-bash"><code class="language-bash">Result:20
<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>上面创建的线程是类型不安全的，那用什么样的方式执行带传入参数的线程的方法是类型安全的呢，答案就是创建一个自定义类，在类中定义一个作为传入参数的字段，将线程的主方法定义为一个类的实例方法。然而使用这种方法就可以使用泛型来解决使用ParameterizedThreadStart的类型不安全:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">class</span> <span class="token class-name">Program</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            #region 使用自定义类实现带参数的线程
            MyThread<span class="token operator">&lt;</span>string<span class="token operator">></span> mythread <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyThread</span><span class="token operator">&lt;</span>string<span class="token operator">></span><span class="token punctuation">(</span><span class="token string">"Thread_child"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            Thread th3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>mythread<span class="token punctuation">.</span>ThreadChild<span class="token punctuation">)</span><span class="token punctuation">;</span>
            th3<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            #endregion
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">MyThread</span><span class="token operator">&lt;</span>T<span class="token operator">></span>
<span class="token punctuation">{</span>
    <span class="token keyword">private</span> T data<span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token function">MyThread</span><span class="token punctuation">(</span>T data<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> data<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">ThreadChild</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Child Thread Start! Result:{0}"</span><span class="token punctuation">,</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果:</p>
<pre class="line-numbers language-bash"><code class="language-bash">Child Thread Start<span class="token operator">!</span> Result:Thread_child
<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<h4 id="关于后台线程"><a href="#关于后台线程" class="headerlink" title="关于后台线程"></a>关于后台线程</h4><p>前台线程的概念：</p>
<ul>
<li>只要有一个前台线程在运行，应用程序的进程就在运行。如果有多个前台线程在运行，而Main()方法（主线程）结束了，应用程序的进程就仍然是激活的，直到所有前台线程完成其任务为止。</li>
</ul>
<p>后台线程的概念：</p>
<ul>
<li>和前台线程相反。当主线程结束后，应用程序的进程就终止了，在所有前台线程结束后，后台线程就会被终止。</li>
</ul>
<blockquote>
<p>Thread类默认创建的是前台线程，所以我们前面创建的线程全部都是前台线程。</p>
</blockquote>
<p>　　在编码的时候我们可以设置<code>Thread</code>类的<code>IsBackground</code>的属性来确定该线程是前台线程还是后台线程。当<code>IsBackground</code>设置为<code>False</code>的时候，为前台线程，设置为<code>Ture</code>的时候为后台线程，下面我们举例来说明前台线程和后台线程的区别。首先我们创建一个前台线程:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Thread th_pre <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>Thread_pre<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>Name<span class="token operator">=</span><span class="token string">"Thread_pre"</span><span class="token punctuation">,</span>IsBackground<span class="token operator">=</span>flase<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">;</span>
    th_pre<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"主线程执行完成！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Thread_pre</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"子线程开始执行！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"子线程执行完成！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果：</p>
<pre class="line-numbers language-bash"><code class="language-bash">主线程执行完成！
子线程开始执行！
子线程执行完成！
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>从上面的运行结果可以看到，当主线程执行完成后，应用程序终止前就会子线程执行完成。</p>
<p>后台线程：</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
　　　　　　　Thread th_back <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>Thread_back<span class="token punctuation">)</span>
　　　　　　　<span class="token punctuation">{</span> Name<span class="token operator">=</span><span class="token string">"Thread_back"</span><span class="token punctuation">,</span>IsBackground<span class="token operator">=</span><span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
    th_back<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"主线程执行完成！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Thread_back</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"子线程开始执行！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"子线程执行完成！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果：</p>
<pre class="line-numbers language-java"><code class="language-java">主线程执行完成！
子线程开始执行！
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>从运行结果可以看出，当主线程结束后，进程就终止了，后台线程也被终止，所以没有后台线程结束的输出信息</p>
<h4 id="控制线程"><a href="#控制线程" class="headerlink" title="控制线程"></a>控制线程</h4><p>我们使用Thread创建线程后，我们需要对线程进行控制。<br>　　1、  使用Start()方法使线程处于Running状态，线程开始执行。<br>　　2、  使用Join（）方法使线程处于WaitSleepJoin状态，在继续执行标准的 COM 和 SendMessage 消息泵处理期间，阻塞调用线程，直到某个线程终止或经过了指定时   间为止。<br>　　3、  使用Sleep()方法，也会使线程处于WaitSleepJoin状态，在经历Sleep()方法定义的时间段后，线程就会被再次唤醒。、<br>　　4、  使用Abort()方法，会使线程处于ResetAbort()状态，线程在接到这个命令的时候，会抛出一个ThradAbordException类型的异常。</p>
<pre class="line-numbers language-java"><code class="language-java">
<span class="token keyword">class</span> <span class="token class-name">Program</span>
<span class="token punctuation">{</span>
    <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"mainThread Start!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Thread th <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>newThread<span class="token punctuation">)</span><span class="token punctuation">;</span>
        th<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//将当前实例的状态更改为 ThreadState.Running。</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"newThread State:{0}"</span><span class="token punctuation">,</span>th<span class="token punctuation">.</span>ThreadState<span class="token punctuation">)</span><span class="token punctuation">;</span>
        th<span class="token punctuation">.</span><span class="token function">Join</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//在继续执行标准的 COM 和 SendMessage 消息泵处理期间，阻塞调用线程，直到某个线程终止或经过了指定时间为止。</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"newThread State:{0}"</span><span class="token punctuation">,</span> th<span class="token punctuation">.</span>ThreadState<span class="token punctuation">)</span><span class="token punctuation">;</span>
        th<span class="token punctuation">.</span><span class="token function">Abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//在调用此方法的线程上引发 ThreadAbortException，以开始终止此线程的过程。 调用此方法通常会终止线程。</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"newThread State:{0}"</span><span class="token punctuation">,</span> th<span class="token punctuation">.</span>ThreadState<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">newThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"newThread Start!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">10000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"newThread Complete!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>


<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><a href="http://www.cnblogs.com/lvcy/archive/2012/06/16/2551539.html" target="_blank" rel="noopener">参考链接</a></p>
<h3 id="使用线程池"><a href="#使用线程池" class="headerlink" title="使用线程池"></a>使用线程池</h3><h4 id="创建线程"><a href="#创建线程" class="headerlink" title="创建线程"></a>创建线程</h4><p>线程池使用<code>ThreadPool</code>类的<code>QueueUserWorkItem</code>方法创建线程，此方法可传递一个委托：</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token comment" spellcheck="true">/// &lt;summary></span>
<span class="token comment" spellcheck="true">/// 一个比较耗时耗资源的私有方法</span>
<span class="token comment" spellcheck="true">/// &lt;/summary></span>
<span class="token comment" spellcheck="true">/// &lt;param name="name">&lt;/param></span>
<span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">DoSomethingLong</span><span class="token punctuation">(</span>string name<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"****************DoSomethingLong Start {name} {Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToString("</span>yyyy<span class="token operator">-</span>MM<span class="token operator">-</span>dd HH<span class="token operator">:</span>mm<span class="token operator">:</span>ss fff<span class="token string">")}***************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">long</span> lResult <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">2000000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        lResult <span class="token operator">+=</span> i<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">//Thread.Sleep(2000);</span>

    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"****************DoSomethingLong   End  {name} {Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToString("</span>yyyy<span class="token operator">-</span>MM<span class="token operator">-</span>dd HH<span class="token operator">:</span>mm<span class="token operator">:</span>ss fff<span class="token string">")}***************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


ThreadPool<span class="token punctuation">.</span><span class="token function">QueueUserWorkItem</span><span class="token punctuation">(</span>t <span class="token operator">=</span><span class="token operator">></span>
<span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">DoSomethingLong</span><span class="token punctuation">(</span><span class="token string">"btnThreadPool_Click"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//耗时操作</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="异步编程模型（APM）"><a href="#异步编程模型（APM）" class="headerlink" title="异步编程模型（APM）"></a>异步编程模型（APM）</h3><p>异步编程模型 (APM)是.NET1.0的时候就已经推出的古老异步编程模式，此模式基于IAsyncResult接口实现。</p>
<p><code>BeginInvoke</code>:开始异步执行委托。<br><code>EndInvoke</code>:获取异步执行结果。</p>
<h4 id="使用BeginInvoke异步执行无返回值委托"><a href="#使用BeginInvoke异步执行无返回值委托" class="headerlink" title="使用BeginInvoke异步执行无返回值委托"></a>使用<code>BeginInvoke</code>异步执行无返回值委托</h4><p>示例：</p>
<pre class="line-numbers language-java"><code class="language-java">Action myNoParAction <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Action</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"无参数委托方法体"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">;</span>
myNoParAction<span class="token punctuation">.</span><span class="token function">BeginInvoke</span><span class="token punctuation">(</span>t <span class="token operator">=</span><span class="token operator">></span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"这是回调"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>t<span class="token punctuation">.</span>AsyncState<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">"这是回调参数"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"主线程***********"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果为：</p>
<pre class="line-numbers language-bash"><code class="language-bash">主线程***********
无参数委托方法体
这是回调
这是回调参数
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>异步执行带参数的委托：</p>
<pre class="line-numbers language-java"><code class="language-java">Action<span class="token operator">&lt;</span>string<span class="token operator">></span> myAction <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Action</span><span class="token operator">&lt;</span>string<span class="token operator">></span><span class="token punctuation">(</span>t <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"委托方法体"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">;</span>
myAction<span class="token punctuation">.</span><span class="token function">BeginInvoke</span><span class="token punctuation">(</span><span class="token string">"参数来了"</span><span class="token punctuation">,</span> t <span class="token operator">=</span><span class="token operator">></span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"这是回调"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>t<span class="token punctuation">.</span>AsyncState<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> null<span class="token punctuation">)</span><span class="token punctuation">;</span>
Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"主线程*************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果为：</p>
<pre class="line-numbers language-bash"><code class="language-bash">主线程*************
委托方法体
参数来了
这是回调

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>回调方法的参数使用<code>AsyncState</code>来接收，无参数则为<code>null</code>。</p>
</blockquote>
<h4 id="使用EndInvoke获取异步执行的返回结果"><a href="#使用EndInvoke获取异步执行的返回结果" class="headerlink" title="使用EndInvoke获取异步执行的返回结果"></a>使用<code>EndInvoke</code>获取异步执行的返回结果</h4><p>示例如下：</p>
<pre class="line-numbers language-java"><code class="language-java"> Func<span class="token operator">&lt;</span>string<span class="token operator">></span> myAction <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Func</span><span class="token operator">&lt;</span>string<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span>
<span class="token punctuation">{</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"委托方法体"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">"这是委托返回值"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">;</span>
IAsyncResult asyncResult <span class="token operator">=</span> myAction<span class="token punctuation">.</span><span class="token function">BeginInvoke</span><span class="token punctuation">(</span>t <span class="token operator">=</span><span class="token operator">></span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"这是回调"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>t<span class="token punctuation">.</span>AsyncState<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> null<span class="token punctuation">)</span><span class="token punctuation">;</span>

string result <span class="token operator">=</span>  myAction<span class="token punctuation">.</span><span class="token function">EndInvoke</span><span class="token punctuation">(</span>asyncRes
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果为：</p>
<pre class="line-numbers language-bash"><code class="language-bash">委托方法体
这是回调

这是委托返回值
主线程*************
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>从返回结果可以看出，在调用<code>EndInvoke</code>时会等待异步操作完成，阻塞主线程。</p>
</blockquote>
<h3 id="基于任务的异步模式（TAP）"><a href="#基于任务的异步模式（TAP）" class="headerlink" title="基于任务的异步模式（TAP）"></a>基于任务的异步模式（TAP）</h3><h4 id="任务的创建"><a href="#任务的创建" class="headerlink" title="任务的创建"></a>任务的创建</h4><p>示例代码如下:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
   <span class="token comment" spellcheck="true">//创建方式1</span>
    TaskFactory tf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TaskFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    tf<span class="token punctuation">.</span><span class="token function">StartNew</span><span class="token punctuation">(</span>TaskMethod <span class="token punctuation">,</span><span class="token string">"使用new TaskFactory()创建"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment" spellcheck="true">//创建方式2</span>
    Task<span class="token punctuation">.</span>Factory<span class="token punctuation">.</span><span class="token function">StartNew</span><span class="token punctuation">(</span>TaskMethod<span class="token punctuation">,</span> <span class="token string">"使用Task.Factory创建"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment" spellcheck="true">//创建方式3</span>
    Task task <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Task</span><span class="token punctuation">(</span>TaskMethod<span class="token punctuation">,</span> <span class="token string">"使用new Task创建"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    task<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    Console<span class="token punctuation">.</span><span class="token function">ReadKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">//线程锁</span>
<span class="token keyword">static</span> object tasklock <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">TaskMethod</span><span class="token punctuation">(</span>object title<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">lock</span> <span class="token punctuation">(</span>tasklock<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>title<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Task Id :{0},Thread:{1}"</span><span class="token punctuation">,</span> Task<span class="token punctuation">.</span>CurrentId<span class="token operator">==</span>null<span class="token operator">?</span><span class="token string">"no task"</span><span class="token operator">:</span>Task<span class="token punctuation">.</span>CurrentId<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId<span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"是否属于线程池:{0}\n"</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>IsThreadPoolThread<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果如下:</p>
<pre class="line-numbers language-bash"><code class="language-bash">使用Task.Factory创建
Task Id :1,Thread:5
是否属于线程池:True

使用new TaskFactory<span class="token punctuation">(</span><span class="token punctuation">)</span>创建
Task Id :2,Thread:4
是否属于线程池:True

使用new Task创建
Task Id :3,Thread:3
是否属于线程池:True
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>以上示例中的三种方式均可创建异步任务,并且都在线程池中运行。</p>
</blockquote>
<h4 id="任务等待和回调的异步任务"><a href="#任务等待和回调的异步任务" class="headerlink" title="任务等待和回调的异步任务"></a>任务等待和回调的异步任务</h4><ol>
<li><code>WaitAll</code>等待集合中所有任务执行完后继续。</li>
<li><code>WaitAny</code>等待集合中任一任务执行完成。</li>
<li><code>ContinueWhenAny</code>任意一个任务完成后要执行的异步任务。</li>
<li><code>ContinueWhenAll</code>所有任务完成后要执行的异步任务。</li>
</ol>
<blockquote>
<p>1、2会阻塞主线程，3、4不会</p>
</blockquote>
<p>示例代码如下：</p>
<pre class="line-numbers language-java"><code class="language-java">

<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//任务集合</span>
    List<span class="token operator">&lt;</span>Task<span class="token operator">></span> taskList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Task<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment" spellcheck="true">//创建5个任务</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">5</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        string name <span class="token operator">=</span> string<span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"btnTask_Click_"</span> <span class="token operator">+</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
        Task task <span class="token operator">=</span> Task<span class="token punctuation">.</span>Factory<span class="token punctuation">.</span><span class="token function">StartNew</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token function">DoSomethingLong</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        taskList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>task<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">//taskList中任意一个任务完成后执行的任务 并将自身加入集合</span>
    taskList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Task<span class="token punctuation">.</span>Factory<span class="token punctuation">.</span><span class="token function">ContinueWhenAny</span><span class="token punctuation">(</span>taskList<span class="token punctuation">.</span><span class="token function">ToArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> t <span class="token operator">=</span><span class="token operator">></span>
        <span class="token punctuation">{</span>
            Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>t<span class="token punctuation">.</span>IsCompleted<span class="token punctuation">)</span><span class="token punctuation">;</span>
            Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"ContinueWhenAny"</span> <span class="token operator">+</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment" spellcheck="true">//taskList中所有任务完成任务完成后执行的任务 并将自身加入集合</span>
    taskList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Task<span class="token punctuation">.</span>Factory<span class="token punctuation">.</span><span class="token function">ContinueWhenAll</span><span class="token punctuation">(</span>taskList<span class="token punctuation">.</span><span class="token function">ToArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> tList <span class="token operator">=</span><span class="token operator">></span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>tList<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>IsCompleted<span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"ContinueWhenAll"</span> <span class="token operator">+</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment" spellcheck="true">//回调形式的，全部任务完成后执行的后续动作</span>

    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"before WaitAny"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Task<span class="token punctuation">.</span><span class="token function">WaitAny</span><span class="token punctuation">(</span>taskList<span class="token punctuation">.</span><span class="token function">ToArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//当前线程等待某个任务的完成  </span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"after WaitAny"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"before WaitAll"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Task<span class="token punctuation">.</span><span class="token function">WaitAll</span><span class="token punctuation">(</span>taskList<span class="token punctuation">.</span><span class="token function">ToArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//当前线程等待全部任务的完成  </span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"after WaitAll"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


<span class="token comment" spellcheck="true">/// &lt;summary></span>
<span class="token comment" spellcheck="true">/// 一个比较耗时耗资源的私有方法</span>
<span class="token comment" spellcheck="true">/// &lt;/summary></span>
<span class="token comment" spellcheck="true">/// &lt;param name="name">&lt;/param></span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">DoSomethingLong</span><span class="token punctuation">(</span>string name<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"****************DoSomethingLong Start "</span> <span class="token operator">+</span> name <span class="token operator">+</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId <span class="token operator">+</span> DateTime<span class="token punctuation">.</span>Now<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"yyyy-MM-dd HH:mm:ss fff"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"***************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">long</span> lResult <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">2000000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        lResult <span class="token operator">+=</span> i<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">//Thread.Sleep(2000);</span>

    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"****************DoSomethingLong   End  "</span> <span class="token operator">+</span> name <span class="token operator">+</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId <span class="token operator">+</span> DateTime<span class="token punctuation">.</span>Now<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"yyyy-MM-dd HH:mm:ss fff"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"***************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="同步任务"><a href="#同步任务" class="headerlink" title="同步任务"></a>同步任务</h4><p>使用Task类的实例方法RunSynchronously()可以让任务同步运行，示例代码:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Task task <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Task</span><span class="token punctuation">(</span>TaskMethod<span class="token punctuation">,</span> <span class="token string">"使用new Task创建"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 摘要:</span>
    <span class="token comment" spellcheck="true">//     对当前的 System.Threading.Tasks.TaskScheduler 同步运行 System.Threading.Tasks.Task。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 异常:</span>
    <span class="token comment" spellcheck="true">//   T:System.ObjectDisposedException:</span>
    <span class="token comment" spellcheck="true">//     已释放 System.Threading.Tasks.Task 实例。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">//   T:System.InvalidOperationException:</span>
    <span class="token comment" spellcheck="true">//     System.Threading.Tasks.Task 未处于有效状态，无法启动。它可能已启动、已执行或已取消，或者可能已经以不支持直接计划的方式创建。</span>
    task<span class="token punctuation">.</span><span class="token function">RunSynchronously</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">ReadKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">//线程锁</span>
<span class="token keyword">static</span> object tasklock <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">TaskMethod</span><span class="token punctuation">(</span>object title<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">lock</span> <span class="token punctuation">(</span>tasklock<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>title<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Task Id :{0},Thread:{1}"</span><span class="token punctuation">,</span> Task<span class="token punctuation">.</span>CurrentId<span class="token operator">==</span>null<span class="token operator">?</span><span class="token string">"no task"</span><span class="token operator">:</span>Task<span class="token punctuation">.</span>CurrentId<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId<span class="token punctuation">)</span><span class="token punctuation">;</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"是否属于线程池:{0}\n"</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>IsThreadPoolThread<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果如下:</p>
<pre class="line-numbers language-bash"><code class="language-bash">使用new Task创建
Task Id :1,Thread:1
是否属于线程池:False

Hello
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="对长时间运行的任务使用单独线程"><a href="#对长时间运行的任务使用单独线程" class="headerlink" title="对长时间运行的任务使用单独线程"></a>对长时间运行的任务使用单独线程</h4><p>如果任务的代码需要长时间运行，就应该使用TaskCreationOptions.LongRunning告诉任务调度器创建一个新线程来运行此任务，而不是使用线程池中的线程。因为在线程池中，任务调度器可能会在创建其他任务时等待当前任务完成。<br>示例如下：</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 摘要:</span>
    <span class="token comment" spellcheck="true">//     指定任务将是长时间运行的、粗粒度的操作，涉及比细化的系统更少、更大的组件。它会向 System.Threading.Tasks.TaskScheduler</span>
    <span class="token comment" spellcheck="true">//     提示，过度订阅可能是合理的。您可以通过过度订阅创建比可用硬件线程数更多的线程。</span>
    Task task <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Task</span><span class="token punctuation">(</span>TaskMethod<span class="token punctuation">,</span> <span class="token string">"使用new Task创建"</span><span class="token punctuation">,</span> TaskCreationOptions<span class="token punctuation">.</span>LongRunning<span class="token punctuation">)</span><span class="token punctuation">;</span>
    task<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Task Id :{0},Thread:{1}\n"</span><span class="token punctuation">,</span> Task<span class="token punctuation">.</span>CurrentId <span class="token operator">==</span> null <span class="token operator">?</span> <span class="token string">"no task"</span> <span class="token operator">:</span> Task<span class="token punctuation">.</span>CurrentId<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">ReadKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">TaskMethod</span><span class="token punctuation">(</span>object title<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>title<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Task Id :{0},Thread:{1}"</span><span class="token punctuation">,</span> Task<span class="token punctuation">.</span>CurrentId <span class="token operator">==</span> null <span class="token operator">?</span> <span class="token string">"no task"</span> <span class="token operator">:</span> Task<span class="token punctuation">.</span>CurrentId<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"是否属于线程池:{0}\n"</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>IsThreadPoolThread<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果如下：</p>
<pre class="line-numbers language-bash"><code class="language-bash">Hello
Task Id :no task,Thread:1

使用new Task创建
Task Id :1,Thread:3
是否属于线程池:False
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="创建具有返回值的异步任务"><a href="#创建具有返回值的异步任务" class="headerlink" title="创建具有返回值的异步任务"></a>创建具有返回值的异步任务</h4><p>使用泛型Task<tresult>可创建具有返回值的异步任务，示例代码如下:</tresult></p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 摘要:</span>
    <span class="token comment" spellcheck="true">//     使用指定的函数和状态初始化新的 System.Threading.Tasks.Task`1。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 参数:</span>
    <span class="token comment" spellcheck="true">//   function:</span>
    <span class="token comment" spellcheck="true">//     表示要在任务中执行的代码的委托。在完成此函数后，该任务的 System.Threading.Tasks.Task`1.Result 属性将设置为返回此函数的结果值。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">//   state:</span>
    <span class="token comment" spellcheck="true">//     一个表示由该操作使用的数据的对象。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 异常:</span>
    <span class="token comment" spellcheck="true">//   T:System.ArgumentNullException:</span>
    <span class="token comment" spellcheck="true">//     function 参数为 null。</span>
    Task<span class="token operator">&lt;</span>string<span class="token operator">></span> task <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Task</span><span class="token operator">&lt;</span>string<span class="token operator">></span><span class="token punctuation">(</span>TaskMethod<span class="token punctuation">,</span><span class="token string">"来自Main的参数"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    task<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    task<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//等待任务执行完成</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>task<span class="token punctuation">.</span>Result<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"执行完成"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">ReadKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">static</span> string <span class="token function">TaskMethod</span><span class="token punctuation">(</span>object title<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>title<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Task Id :{0},Thread:{1}"</span><span class="token punctuation">,</span> Task<span class="token punctuation">.</span>CurrentId <span class="token operator">==</span> null <span class="token operator">?</span> <span class="token string">"no task"</span> <span class="token operator">:</span> Task<span class="token punctuation">.</span>CurrentId<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>ManagedThreadId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"是否属于线程池:{0}\n"</span><span class="token punctuation">,</span> Thread<span class="token punctuation">.</span>CurrentThread<span class="token punctuation">.</span>IsThreadPoolThread<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">"来自TaskMethod的返回值"</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果为:</p>
<pre class="line-numbers language-bash"><code class="language-bash">来自Main的参数
Task Id :1,Thread:3
是否属于线程池:True

来自TaskMethod的返回值
执行完成
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>等待任务执行完成的方法:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token comment" spellcheck="true">//等待当前 System.Threading.Tasks.Task 完成执行过程。</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">//等待传入的所有任务完成  </span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">WaitAll</span><span class="token punctuation">(</span>params Task<span class="token punctuation">[</span><span class="token punctuation">]</span> tasks<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">//等待传入的任意一个任务完成</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">WaitAny</span><span class="token punctuation">(</span>params Task<span class="token punctuation">[</span><span class="token punctuation">]</span> tasks<span class="token punctuation">)</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>在获取任务的返回值时，如果任务尚未执行完成，则Result属性将被禁用并会等待任务执行完成，所以示例中不加task.Wait()执行结果也一样。</p>
</blockquote>
<h4 id="延续的任务"><a href="#延续的任务" class="headerlink" title="延续的任务"></a>延续的任务</h4><p>在任务上调用ContinueWith()方法来启动当前任务完成后的任务。<br>示例如下：</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Main</span><span class="token punctuation">(</span>string<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Task t <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Task</span><span class="token punctuation">(</span>One<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Task t1<span class="token operator">=</span> t<span class="token punctuation">.</span><span class="token function">ContinueWith</span><span class="token punctuation">(</span>Two<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Task t2 <span class="token operator">=</span> t1<span class="token punctuation">.</span><span class="token function">ContinueWith</span><span class="token punctuation">(</span>Two<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Task t3 <span class="token operator">=</span> t2<span class="token punctuation">.</span><span class="token function">ContinueWith</span><span class="token punctuation">(</span>Two<span class="token punctuation">)</span><span class="token punctuation">;</span>
    t<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">One</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"TaskID:{0}"</span> <span class="token punctuation">,</span> Task<span class="token punctuation">.</span>CurrentId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"this is One\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Two</span><span class="token punctuation">(</span>Task t<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"t Id:{0}"</span><span class="token punctuation">,</span> t<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"TaskID:{0}"</span><span class="token punctuation">,</span>Task<span class="token punctuation">.</span>CurrentId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"this is Two\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果如下：</p>
<pre class="line-numbers language-bash"><code class="language-bash">TaskID:1
this is One

t Id:1
TaskID:2
this is Two

t Id:2
TaskID:3
this is Two

t Id:3
TaskID:4
this is Two
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>使用ContinueWith()方法时，无论前面一个任务是如何结束的，哪怕是发生异常，也会在结束时启动下一个任务，使用TaskContinuationOptions中的枚举值来指定如何启动延续任务，TaskContinuationOptions中指定延续任务启动条件的值如下:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     Default = "Continue on any, no task options, run asynchronously" 指定应使用默认行为。默认情况下，完成前面的任务之后将安排运行延续任务，而不考虑前面任务的最终</span>
<span class="token comment" spellcheck="true">//     System.Threading.Tasks.TaskStatus。</span>
None <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     提示 System.Threading.Tasks.TaskScheduler 以一种尽可能公平的方式安排任务，这意味着较早安排的任务将更可能较早运行，而较晚安排运行的任务将更可能较晚运行。</span>
PreferFairness <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定某个任务将是运行时间长、粗粒度的操作。它会向 System.Threading.Tasks.TaskScheduler 提示，过度订阅可能是合理的。</span>
LongRunning <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定将任务附加到任务层次结构中的某个父级。</span>
AttachedToParent <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     如果尝试附有子任务到创建的任务，指定 System.InvalidOperationException 将被引发。</span>
DenyChildAttach <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     防止环境计划程序被视为已创建任务的当前计划程序。这意味着像 StartNew 或 ContinueWith 创建任务的执行操作将被视为 System.Threading.Tasks.TaskScheduler.Default</span>
<span class="token comment" spellcheck="true">//     当前计划程序。</span>
HideScheduler <span class="token operator">=</span> <span class="token number">16</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     在延续取消的情况下，防止延续的完成直到完成先前的任务。</span>
LazyCancellation <span class="token operator">=</span> <span class="token number">32</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定不应在延续任务前面的任务已完成运行的情况下安排延续任务。此选项对多任务延续无效。</span>
NotOnRanToCompletion <span class="token operator">=</span> <span class="token number">65536</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定不应在延续任务前面的任务引发了未处理异常的情况下安排延续任务。此选项对多任务延续无效。</span>
NotOnFaulted <span class="token operator">=</span> <span class="token number">131072</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定只应在延续任务前面的任务已取消的情况下安排延续任务。此选项对多任务延续无效。</span>
OnlyOnCanceled <span class="token operator">=</span> <span class="token number">196608</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定不应在延续任务前面的任务已取消的情况下安排延续任务。此选项对多任务延续无效。</span>
NotOnCanceled <span class="token operator">=</span> <span class="token number">262144</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定只有在延续任务前面的任务引发了未处理异常的情况下才应安排延续任务。此选项对多任务延续无效。</span>
OnlyOnFaulted <span class="token operator">=</span> <span class="token number">327680</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定只应在延续任务前面的任务已完成运行的情况下才安排延续任务。此选项对多任务延续无效。</span>
OnlyOnRanToCompletion <span class="token operator">=</span> <span class="token number">393216</span><span class="token punctuation">,</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">// 摘要:</span>
<span class="token comment" spellcheck="true">//     指定应同步执行延续任务。指定此选项后，延续任务将在导致前面的任务转换为其最终状态的相同线程上运行。如果在创建延续任务时已经完成前面的任务，则延续任务将在创建此延续任务的线程上运行。只应同步执行运行时间非常短的延续任务。</span>
ExecuteSynchronously <span class="token operator">=</span> <span class="token number">524288</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="任务的层次结构（父-子任务）"><a href="#任务的层次结构（父-子任务）" class="headerlink" title="任务的层次结构（父/子任务）"></a>任务的层次结构（父/子任务）</h4><p>在一个任务的内部启动另一个任务时，任务便会形成一种层次结构，如果父任务在子任务之前结束，父任务的状态为:WaitingForChildrenToComplete,可在子任务创建时使用TaskCreationOptions指定父子任务如何运行。</p>
<h3 id="线程等待、取消和异常处理"><a href="#线程等待、取消和异常处理" class="headerlink" title="线程等待、取消和异常处理"></a>线程等待、取消和异常处理</h3><h4 id="线程取消和异常处理"><a href="#线程取消和异常处理" class="headerlink" title="线程取消和异常处理"></a>线程取消和异常处理</h4><p>线程间都是通过共有变量：都能访问局部变量/全局变量/数据库的一个值/硬盘文件来通信。<br>线程不能被外部停止，只能自身停止自身；或者在任务启动前停止，会抛出<code>AggregateException</code>异常的</p>
<p>步骤：</p>
<ol>
<li>使用<code>CancellationTokenSource</code>类的实例作为公共变量</li>
<li><code>CancellationTokenSource</code>类的<code>Cancel</code>方法指示线程取消。</li>
<li><code>IsCancellationRequested</code>属性判断是否被取消。</li>
</ol>
<p>示例代码如下：</p>
<pre class="line-numbers language-java"><code class="language-java">TaskFactory taskFactory <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TaskFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
List<span class="token operator">&lt;</span>Task<span class="token operator">></span> taskList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Task<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
CancellationTokenSource cts <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CancellationTokenSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">40</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    string name <span class="token operator">=</span> string<span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"btnThreadCore_Click{0}"</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    Action<span class="token operator">&lt;</span>object<span class="token operator">></span> act <span class="token operator">=</span> t <span class="token operator">=</span><span class="token operator">></span>
    <span class="token punctuation">{</span>
        <span class="token keyword">try</span>
        <span class="token punctuation">{</span>
            <span class="token comment" spellcheck="true">//if (cts.IsCancellationRequested)</span>
            <span class="token comment" spellcheck="true">//{</span>
            <span class="token comment" spellcheck="true">//    Console.WriteLine("{0} 取消一个任务的执行", t);</span>
            <span class="token comment" spellcheck="true">//}</span>
            Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>t<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"btnThreadCore_Click11"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Exception</span><span class="token punctuation">(</span>string<span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"{0} 执行失败"</span><span class="token punctuation">,</span> t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>t<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"btnThreadCore_Click12"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Exception</span><span class="token punctuation">(</span>string<span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"{0} 执行失败"</span><span class="token punctuation">,</span> t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>cts<span class="token punctuation">.</span>IsCancellationRequested<span class="token punctuation">)</span><span class="token comment" spellcheck="true">//检查信号量</span>
            <span class="token punctuation">{</span>
                Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"{0} 放弃执行"</span><span class="token punctuation">,</span> t<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">else</span>
            <span class="token punctuation">{</span>
                Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"{0} 执行成功"</span><span class="token punctuation">,</span> t<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> ex<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            cts<span class="token punctuation">.</span><span class="token function">Cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//表示修改了信号量  让大家取消执行</span>
            Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>ex<span class="token punctuation">.</span>Message<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    taskList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>taskFactory<span class="token punctuation">.</span><span class="token function">StartNew</span><span class="token punctuation">(</span>act<span class="token punctuation">,</span> name<span class="token punctuation">,</span> cts<span class="token punctuation">.</span>Token<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//没有启动的任务  在Cancel后放弃启动</span>
<span class="token punctuation">}</span>
Task<span class="token punctuation">.</span><span class="token function">WaitAll</span><span class="token punctuation">(</span>taskList<span class="token punctuation">.</span><span class="token function">ToArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果为：</p>
<pre class="line-numbers language-bash"><code class="language-bash">btnThreadCore_Click1 执行成功
btnThreadCore_Click0 执行成功
btnThreadCore_Click3 执行成功
btnThreadCore_Click2 执行成功
btnThreadCore_Click4 执行成功
btnThreadCore_Click5 执行成功
btnThreadCore_Click7 执行成功
btnThreadCore_Click6 执行成功
btnThreadCore_Click8 执行成功
btnThreadCore_Click9 执行成功
btnThreadCore_Click10 执行成功
btnThreadCore_Click11 执行失败
btnThreadCore_Click13 放弃执行
btnThreadCore_Click12 执行失败
btnThreadCore_Click14 放弃执行
btnThreadCore_Click15 放弃执行
btnThreadCore_Click16 放弃执行
btnThreadCore_Click17 放弃执行
btnThreadCore_Click18 放弃执行
btnThreadCore_Click19 放弃执行
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>这段代码在执行到WaitAll时会抛出<code>AggregateException</code>异常。</p>
<p>这就引出了多线程中的异常处理问题，在多线程的代码块中所有抛出的异常都不会被主线程截获到，只有在任务WaitAll时才会抛出异常，所以应该在异步任务中使用try-catch语句块记录日志，在WaitAll外处理异常。</p>
<h4 id="线程等待：给Thread、ThreadPool封装异步回调方法"><a href="#线程等待：给Thread、ThreadPool封装异步回调方法" class="headerlink" title="线程等待：给Thread、ThreadPool封装异步回调方法"></a>线程等待：给Thread、ThreadPool封装异步回调方法</h4><p>封装示例如下:</p>
<pre class="line-numbers language-java"><code class="language-java"><span class="token comment" spellcheck="true">/// &lt;summary></span>
<span class="token comment" spellcheck="true">/// 无返回值，支持回调</span>
<span class="token comment" spellcheck="true">/// &lt;/summary></span>
<span class="token comment" spellcheck="true">/// &lt;param name="action">&lt;/param></span>
<span class="token comment" spellcheck="true">/// &lt;param name="callBack">&lt;/param></span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">CallBack</span><span class="token punctuation">(</span>Action action<span class="token punctuation">,</span> Action callBack<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 摘要:</span>
    <span class="token comment" spellcheck="true">//     用一个指示是否将初始状态设置为终止的布尔值初始化 System.Threading.ManualResetEvent 类的新实例。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 参数:</span>
    <span class="token comment" spellcheck="true">//   initialState:</span>
    <span class="token comment" spellcheck="true">//     如果为 true，则将初始状态设置为终止；如果为 false，则将初始状态设置为非终止。</span>
    ManualResetEvent mre <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ManualResetEvent</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    WaitCallback act <span class="token operator">=</span> state <span class="token operator">=</span><span class="token operator">></span>
    <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">//执行主方法</span>
        action<span class="token punctuation">.</span><span class="token function">Invoke</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">//主方法执行完  可以执行回调方法了</span>
        mre<span class="token punctuation">.</span><span class="token function">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">//回调方法的线程</span>
        WaitCallback call <span class="token operator">=</span> t <span class="token operator">=</span><span class="token operator">></span>
        <span class="token punctuation">{</span>
            <span class="token comment" spellcheck="true">//等待收到Set信号</span>
            mre<span class="token punctuation">.</span><span class="token function">WaitOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment" spellcheck="true">//执行回调方法</span>
            callBack<span class="token punctuation">.</span><span class="token function">Invoke</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        ThreadPool<span class="token punctuation">.</span><span class="token function">QueueUserWorkItem</span><span class="token punctuation">(</span>call<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    ThreadPool<span class="token punctuation">.</span><span class="token function">QueueUserWorkItem</span><span class="token punctuation">(</span>act<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>调用：</p>
<pre class="line-numbers language-java"><code class="language-java">
<span class="token function">CallBack</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"异步方法"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span> Thread<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"回调方法"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"主线程"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>输出结果为：</p>
<pre class="line-numbers language-bash"><code class="language-bash">主线程
异步方法
回调方法
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>对Thread的封装如下:</p>
<pre class="line-numbers language-java"><code class="language-java">
<span class="token comment" spellcheck="true">/// &lt;summary></span>
<span class="token comment" spellcheck="true">/// 无返回值，支持回调</span>
<span class="token comment" spellcheck="true">/// &lt;/summary></span>
<span class="token comment" spellcheck="true">/// &lt;param name="action">&lt;/param></span>
<span class="token comment" spellcheck="true">/// &lt;param name="callBack">&lt;/param></span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">CallBack</span><span class="token punctuation">(</span>Action action<span class="token punctuation">,</span> Action callBack<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 摘要:</span>
    <span class="token comment" spellcheck="true">//     用一个指示是否将初始状态设置为终止的布尔值初始化 System.Threading.ManualResetEvent 类的新实例。</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">// 参数:</span>
    <span class="token comment" spellcheck="true">//   initialState:</span>
    <span class="token comment" spellcheck="true">//     如果为 true，则将初始状态设置为终止；如果为 false，则将初始状态设置为非终止。</span>
    ManualResetEvent mre <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ManualResetEvent</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    ThreadStart act <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span>
    <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">//执行主方法</span>
        action<span class="token punctuation">.</span><span class="token function">Invoke</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">//主方法执行完  可以执行回调方法了</span>
        mre<span class="token punctuation">.</span><span class="token function">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">//回调方法的线程</span>
        ThreadStart call <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span>
        <span class="token punctuation">{</span>
            <span class="token comment" spellcheck="true">//等待收到Set信号</span>
            mre<span class="token punctuation">.</span><span class="token function">WaitOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment" spellcheck="true">//执行回调方法</span>
            callBack<span class="token punctuation">.</span><span class="token function">Invoke</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
            <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>call<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span>act<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>调用方式和线程池一样。</p>

    </div>
</article>


<div id="comments-template"></div>
<link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css">
<script>
	if(!window.commentConfig) {
      window.commentConfig = {}
      window.commentConfig.title = 'C#多线程'
    }
</script>

                    </div>
                    <aside class="col-md-4 gal-left" id="sidebar">
    <!-- 此为sidebar的搜索框, 非搜索结果页面 -->
<aside id="sidebar-search">
    <div class="search hidden-xs" data-aos="fade-up" data-aos-duration="2000">
        <form class="form-inline clearfix" id="search-form" method="get"
              action="/search/index.html">
            <input type="text" name="s" class="form-control" id="searchInput" placeholder="搜索文章~">
            <button class="btn btn-danger btn-gal" type="submit">
                <i class="fa fa-search"></i>
            </button>
        </form>
    </div>
</aside>
    <aside id="sidebar-author">
    <div class="panel panel-gal" data-aos="flip-right" data-aos-duration="3000">
        <div class="panel-heading" style="text-align: center">
            <i class="fa fa-quote-left"></i>
            Taffy
            <i class="fa fa-quote-right"></i>
        </div>
        <div class="author-panel text-center">
            <img src="/imgs/avatar.jpg" width="140" height="140"
                 alt="个人头像" class="author-image">
            <p class="author-description"><p>纸上得来终觉浅，绝知此事要躬行！</p>
</p>
        </div>
    </div>
</aside>
    
    <aside id="sidebar-recent_comments">
    <div class="panel panel-gal recent hidden-xs" data-aos="fade-up" data-aos-duration="2000">
        <div class="panel-heading">
            <i class="fa fa-comments"></i>
            最新评论
            <i class="fa fa-times-circle panel-remove"></i>
            <i class="fa fa-chevron-circle-up panel-toggle"></i>
        </div>
        <ul class="list-group list-group-flush"></ul>
    </div>
</aside>
    
    <!-- 要配置好leancloud才能开启此小工具 -->
    
    
    <aside id="sidebar-recent_posts">
    <div class="panel panel-gal recent hidden-xs" data-aos="fade-up" data-aos-duration="2000">
        <div class="panel-heading">
            <i class="fa fa-refresh"></i>
            近期文章
            <i class="fa fa-times-circle panel-remove"></i>
            <i class="fa fa-chevron-circle-up panel-toggle"></i>
        </div>
        <ul class="list-group list-group-flush">
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/08/14/vueJsRoute/">VueJs路由入门</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/31/vueJsCompoentData/">VueJs组件间的数据交换</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/30/vueJsComponentSendData/">VueJs组件插槽、动态组件、缓存组件</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/26/vueJswebpack/">VueJs通过webpack启服务运行VUE模块文件</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/25/vuejscmd/">VueJs自定义指令和组件</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/25/vueAttr/">VueJs实例属性</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/20/vueLifeCycle/">VueJs生命周期、计算属性和侦听器</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/17/vueJsFilter/">VueJs过滤器</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/16/vueJsEvent/">VueJs事件操作</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/07/12/vuejstemplete/">VueJs表单数据操作</a>
                </span>
            </li>
            
        </ul>
    </div>
</aside>
    
    
    <aside id="sidebar-rand_posts">
    <div class="panel panel-gal recent hidden-xs" data-aos="fade-up" data-aos-duration="2000">
        <div class="panel-heading">
            <i class="fa fa-refresh"></i>
            随机文章
            <i class="fa fa-times-circle panel-remove"></i>
            <i class="fa fa-chevron-circle-up panel-toggle"></i>
        </div>
        <ul class="list-group list-group-flush">
            
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/01/16/EntityFramework/">EntityFramework建立的三种方式</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/04/09/closureScope/">作用域和闭包</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2017/12/17/cssSelector/">CSS选择器</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2017/05/24/datawidth/">汇编学习(二)--数据宽度</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2017/05/14/httprequestheader/">Http请求头参数</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/04/29/jsSingleton/">Js单例模式</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2017/05/29/linuxInstallOracle/">在Linux中安装Oracle数据库</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2017/05/11/operator/">使用operator进行运算符重载</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/04/09/prototypeAndInherit/">原型和继承</a>
                </span>
            </li>
            
            <li class="list-group-item">
                <span class="post-title">
                    <a href="/2018/05/13/varAndletDifference/">var和let的作用域区别</a>
                </span>
            </li>
            
        </ul>
    </div>
</aside>
    
    
    <aside id="gal-sets">
        <div class="panel panel-gal hidden-xs" data-aos="fade-up" data-aos-duration="2000">
            <ul class="nav nav-pills pills-gal">
                <li class="">
                    <a href="/2017/05/15/task_async/index.html#sidebar-tags" data-toggle="tab" id="tags-tab">热门标签</a>
                </li>
                <li class="">
                    <a href="/2017/05/15/task_async/index.html#sidebar-friend-links" data-toggle="tab" id="friend-links-tab">友情链接</a>
                </li>
                <li class="">
                    <a href="/2017/05/15/task_async/index.html#sidebar-links" data-toggle="tab" id="links-tab">个人链接</a>
                </li>
            </ul>
            <div class="tab-content">
                <div class="cloud-tags tab-pane nav bs-sidenav fade" id="sidebar-tags">
    
    <a href="/tags/结构型设计模式/" style="font-size: 8.647776434676997px;" class="tag-cloud-link">结构型设计模式</a>
    
    <a href="/tags/Javascript/" style="font-size: 13.486915510082458px;" class="tag-cloud-link">Javascript</a>
    
    <a href="/tags/EF6/" style="font-size: 11.297593781498055px;" class="tag-cloud-link">EF6</a>
    
    <a href="/tags/创建型设计模式/" style="font-size: 9.674730083325969px;" class="tag-cloud-link">创建型设计模式</a>
    
    <a href="/tags/程序集/" style="font-size: 15.759071313051411px;" class="tag-cloud-link">程序集</a>
    
    <a href="/tags/CSS/" style="font-size: 10.8996374228442px;" class="tag-cloud-link">CSS</a>
    
    <a href="/tags/javascript/" style="font-size: 8.534564337938548px;" class="tag-cloud-link">javascript</a>
    
    <a href="/tags/正则表达式/" style="font-size: 16.89846094835141px;" class="tag-cloud-link">正则表达式</a>
    
    <a href="/tags/WinForm/" style="font-size: 13.680812527533467px;" class="tag-cloud-link">WinForm</a>
    
    <a href="/tags/多线程/" style="font-size: 12.299545842719784px;" class="tag-cloud-link">多线程</a>
    
    <a href="/tags/Oracle/" style="font-size: 10.15555415488273px;" class="tag-cloud-link">Oracle</a>
    
    <a href="/tags/加密/" style="font-size: 18.540140007283014px;" class="tag-cloud-link">加密</a>
    
    <a href="/tags/ES6/" style="font-size: 18.605468819507074px;" class="tag-cloud-link">ES6</a>
    
    <a href="/tags/VueJs/" style="font-size: 10.144395428943099px;" class="tag-cloud-link">VueJs</a>
    
    <a href="/tags/代码段/" style="font-size: 19.79881169769166px;" class="tag-cloud-link">代码段</a>
    
    <a href="/tags/ASP-NET/" style="font-size: 14.067194382961707px;" class="tag-cloud-link">ASP.NET</a>
    
    <a href="/tags/XML/" style="font-size: 13.17303138091517px;" class="tag-cloud-link">XML</a>
    
    <a href="/tags/数据库/" style="font-size: 15.779940587867609px;" class="tag-cloud-link">数据库</a>
    
</div>
                <div class="friend-links tab-pane nav bs-sidenav fade" id="sidebar-friend-links">
    
    <li>
        <a href="http://www.baidu.com/" target="_blank">百度</a>
    </li>
    
</div>
                <div class="links tab-pane nav bs-sidenav fade" id="sidebar-links">
    
    <li>
        <a href="https://github.com/TaffyBlog" target="_blank">Github</a>
    </li>
    
    <li>
        <a href="https://www.zhihu.com/people/fei-ge-ge-2-8/activities" target="_blank">知乎</a>
    </li>
    
</div>
            </div>
        </div>
    </aside>
    
</aside>
                
            </div>
        </div>
    </div>
    <footer id="gal-footer">
    <div class="container">
        Copyright © 2018 Taffy Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>.&nbsp;Theme by <a href="https://github.com/ZEROKISEKI" target="_blank">AONOSORA</a>
    </div>
</footer>

<!-- 回到顶端 -->
<div id="gal-gotop">
    <i class="fa fa-angle-up"></i>
</div>
<script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","model":{"scale":1,"hHeadPos":0.5,"vHeadPos":0.618,"jsonPath":"/live2dw/assets/assets/hibiki.model.json"},"display":{"superSample":1.5,"width":150,"height":300,"position":"right","hOffset":0,"vOffset":0},"mobile":{"show":true,"scale":0.1},"react":{"opacityDefault":0.7,"opacityOnHover":0.2},"log":false,"tagMode":false});</script></body>
<script src="/js/activate-power-mode.js"></script>
<script>

    // 配置highslide
	hs.graphicsDir = '/js/highslide/graphics/'
    hs.outlineType = "rounded-white";
    hs.dimmingOpacity = 0.8;
    hs.outlineWhileAnimating = true;
    hs.showCredits = false;
    hs.captionEval = "this.thumb.alt";
    hs.numberPosition = "caption";
    hs.align = "center";
    hs.transitions = ["expand", "crossfade"];
    hs.lang.number = '共%2张图, 当前是第%1张';
    hs.addSlideshow({
      interval: 5000,
      repeat: true,
      useControls: true,
      fixedControls: "fit",
      overlayOptions: {
        opacity: 0.75,
        position: "bottom center",
        hideOnMouseOut: true
      }
    })

    // 初始化aos
    AOS.init({
      duration: 1000,
      delay: 0,
      easing: 'ease-out-back'
    });

</script>
<script>
	POWERMODE.colorful = 'true';    // make power mode colorful
	POWERMODE.shake = 'true';       // turn off shake
	// TODO 这里根据具体情况修改
	document.body.addEventListener('input', POWERMODE);
</script>
<script>
    window.slideConfig = {
      prefix: 'http://p9hqbt6wm.bkt.clouddn.com/background',
      ext: 'jpg',
      maxCount: '6'
    }
</script>
<script src="/js/hs.js"></script>
<script src="/js/blog.js"></script>

<script src="/js/oni.js"></script>



<script src="https://imsun.github.io/gitment/dist/gitment.browser.js"></script>
<script>
    if(window.commentConfig) {
      window.commentConfig.id = 'Mon May 15 2017 20:34:26 GMT+0800'
      window.commentConfig.owner = 'TaffyBlog'
      window.commentConfig.repo = 'taffyblogcomments'
      window.commentConfig.client_id = 'fd4a3c1821147e2a3dfe'
      window.commentConfig.client_secret = 'de6bc8eec3ca751089ca7cca196515cb6a4a7c24'
      window.commentConfig.redirect_uri = 'https://taffyblog.github.io'
    } else {
      window.commentConfig = {
      	id: 'Mon May 15 2017 20:34:26 GMT+0800',
        owner: 'TaffyBlog',
        repo: 'taffyblogcomments',
        client_id: 'fd4a3c1821147e2a3dfe',
        client_secret: 'de6bc8eec3ca751089ca7cca196515cb6a4a7c24',
        redirect_uri: 'https://taffyblog.github.io'
      }
    }
</script>
<script src="/js/comment/gitment.js"></script>

</html>